﻿package Modules.CommunicationsModule
{
	import Modules.FarmModule.FarmAbstract;
	import Modules.MainTimeLine;
	import Modules.PlayerModule.Player;
	import Modules.PlayerModule.PlayerUtil;
	
	import com.adobe.serialization.json.*;
	
	import flash.display.Loader;
	import flash.errors.IOError;
	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	
	public class ClientServerCommunications
	{
		//Function to initialise the setting up of a player
		public static function initPlayerSetUp(){
			
			//step 1: check if the player exists in the database or not using the following request
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var checkPlayerRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/get_player.php");
			checkPlayerRequest.method = URLRequestMethod.POST;
			
			//Send the player id over to the server as a variable for checking
			if(MainTimeLine.session.player.playerID != null){
				var loaderVar:URLVariables = new URLVariables();
				loaderVar.facebookId = MainTimeLine.session.player.playerID;
				checkPlayerRequest.data = loaderVar;
			}
			
			//Execute teh request
			try{
				loader.load(checkPlayerRequest);
				
				//Upon completion of function, go to getLogInTime to retrieve the log in time from the server
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{getLogInTime(loader);});
			}catch(error:IOError){
				dump("unable to check player");
			}
		}
		
		//Another loading function
		//retrieves the log in time from the server
		public static function getLogInTime(loader:URLLoader):void{
			
			var timeLoader:URLLoader = new URLLoader();
			var timeRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/get_server_time.php");
			
			try{
				
				//when the loading of server time is completed, and listener to start the game loop is added to the game movieclip
				//log in the player using login();
				timeLoader.addEventListener(Event.COMPLETE, function fx(event:Event):void{trace("updating servertime"); MainTimeLine.serverTime = timeLoader.data; MainTimeLine.root.addEventListener(Event.ENTER_FRAME,MainTimeLine.root.incrementServerTime);  login(loader);});
				timeLoader.load(timeRequest);
				
			}catch(error:IOError){
				dump("unable to get server time");	
			}
		}
		
		public static function getServerTime():void{
			
			var timeLoader:URLLoader = new URLLoader();
			var timeRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/get_server_time.php");
			
			try{
				
				timeLoader.addEventListener(Event.COMPLETE, function fx(event:Event):void{MainTimeLine.serverTime = timeLoader.data;});
				timeLoader.load(timeRequest);
				
			}catch(error:IOError){
				dump("unable to get server time");	
			}
		}
		
		//checks if the player exists in the DB and decides if game should create new player or load
		public static function login(loader:URLLoader):void{
			
			//incoming data string
			var incoming:String = loader.data;
			MainTimeLine.debugText.text = "this is the incoming statement for player loading: "+ incoming;
			
			if((incoming == "new player")||(incoming == "null")){
				
				MainTimeLine.session.newPlayer = true;
				MainTimeLine.debugText.text = "initialising new player";	
				
				//function to generate the player set up panels should be called here
				PlayerUtil.initNewPlayer();
			}else{
				
				MainTimeLine.session.newPlayer = false;
				//MainTimeLine.debugText.text = ("loading player: "+incoming);
				
				//passes the data to player util to instatiate the main player variables
				PlayerUtil.loadPlayer(JSON.decode(incoming));				
			}
			
			loadPlayerFarm();
			MainTimeLine.session.player.logInTime = MainTimeLine.serverTime;
			MainTimeLine.loadedPlayer = true;
		}
		
		//loads the empty inventory containing 0 quantities of all items.
		// tables contain all the items' effects
		public static function loadItemTable():void{
			
			//loaders for the different tables
			var seedloader:URLLoader	 = new URLLoader();
			var foodloader:URLLoader	 = new URLLoader();
			var decoloader:URLLoader	 = new URLLoader();
			var buildingloader:URLLoader = new URLLoader();
			
			//addresses of the  respective php scripts
			var seedRequest:URLRequest		= new URLRequest(MainTimeLine.rootURL+"PHP/inventory/get_seeds.php");
			seedRequest.method = URLRequestMethod.POST;
			
			var foodRequest:URLRequest		= new URLRequest(MainTimeLine.rootURL+"PHP/inventory/get_food.php");
			foodRequest.method = URLRequestMethod.POST;
			
			var decoRequest:URLRequest		= new URLRequest(MainTimeLine.rootURL+"PHP/inventory/get_decorations.php");
			decoRequest.method = URLRequestMethod.POST;
			
			var buildingRequest:URLRequest	= new URLRequest(MainTimeLine.rootURL+"PHP/inventory/get_buildings.php");
			buildingRequest.method = URLRequestMethod.POST;
			
			//attempt to load the tables and moves to the completion function after loading.
			try{
				seedloader.load(seedRequest);
				seedloader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadTable(seedloader,"seed");});
			}catch(error:IOError){
				dump("failed to load seed table");	
			}
			
			try{
				foodloader.load(foodRequest);
				foodloader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadTable(foodloader,"food");});
			}catch(error:IOError){
				dump("failed to load food table");	
			}
			
			try{
				decoloader.load(decoRequest);
				decoloader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadTable(decoloader,"deco");});
			}catch(error:IOError){
				dump("failed to load deco table");	
			}
			
			try{
				buildingloader.load(buildingRequest);
				buildingloader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadTable(buildingloader,"building");});
			}catch(error:IOError){
				dump("failed to load building table");	
			}	
		}
		
		//generic function to handle the load event completions
		//for all five types of items
		public static function completeLoadTable(loader:URLLoader, type:String):void{
			
			//instantiate variables
			var loadedArray:Array = [];
			var decodedArray:Array = [];
			var incoming:String = loader.data;
			
			//checks if all incoming data are valid
			if(incoming.search("Warning")<0){
				
				//incoming = incoming.replace("\r\n","");
				//break down the incoming data into item JSOn Strings
				loadedArray = incoming.split("|");
				
				var length:int = loadedArray.length-1;
				var i:int=0;
				
				//decode array and push it into decoded array
				for( i; i<length; i++){
					
					if(loadedArray[i] != null){
						decodedArray.push(JSON.decode(loadedArray[i]));
						decodedArray[i].name = ((decodedArray[i].name as String).split("\r"))[0];
					}
				}
				
				dump(type+ "table loaded");
				
			}else{
				dump(type +" loading failed... check database");
			}
			
			//passes the arrays to the respective methods to instantiate items
			switch(type){
				
				case "seed":
					MainTimeLine.session.player.inventory.itemTable.setSeedTable(decodedArray);
					
					break;
				
				case "food":
					MainTimeLine.session.player.inventory.itemTable.setFoodTable(decodedArray);
					
					break;				
				
				case "deco":
					MainTimeLine.session.player.inventory.itemTable.setDecorationTable(decodedArray);
					
					break;
				
				case "building":
					MainTimeLine.session.player.inventory.itemTable.setBuildingTable(decodedArray);
					
					break;
			}
		}
		
		public static function loadPlayerInventory(playerID:String):void{
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var loaderVar:URLVariables = new URLVariables();
			
			//retrieve playerid from facebook
			loaderVar.facebookId = playerID;
			
			var loadInventoryRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/inventory/get_player_inventory.php");
			loadInventoryRequest.method = URLRequestMethod.POST;
			
			loadInventoryRequest.data = loaderVar;
			
			//attempt loading of the inventory
			try{
				loader.load(loadInventoryRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadPlayerInventory(loader);});
			}catch(error:IOError){
				trace("unable to load inventory");
				dump("unable to load player inventory");	
			}
		}
		
		public static function completeLoadPlayerInventory(loader:URLLoader):void{
			
			var decodedObject:Array = JSON.decode(JSON.decode(loader.data).itemData) as Array;
			MainTimeLine.session.player.initInventory(decodedObject);			
		}
		
		//Function to load the main player's farm from the database
		public static function loadPlayerFarm():void{
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var loaderVar:URLVariables = new URLVariables();
			
			//retrieve playerid from facebook
			loaderVar.facebookId = MainTimeLine.session.player.playerID;
			
			//php script to load the inventory	
			var loadFarmRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/get_player_farm.php"); //input check script url here
			loadFarmRequest.method = URLRequestMethod.POST;
			
			loadFarmRequest.data = loaderVar;
			
			//attempt loading of the inventory
			try{
				loader.load(loadFarmRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadPlayerFarm(loader);});
			}catch(error:IOError){
				dump("unable to load player farm");	
			}
		}
		
		//Completion function for loading player's farm
		public static function completeLoadPlayerFarm(loader:URLLoader):void{
			
			//instantiate variables
			var decodedArray:Array = [];
			var incoming:String = loader.data;
			//MainTimeLine.debugText.text = incoming;
		
			//checks if all incoming data are valid
			if((incoming.search("Warning")<0)&&(incoming.length>1)){
				//If valid, decoded array will be replaced by the
				//loaded data
				decodedArray = JSON.decode(incoming);				
			}else{
				dump(" player farm loading failed... please check database for errors");
			}
			
			//The current player should have a function to complete the load farm function
			//Use it here
			MainTimeLine.session.player.initFarm(decodedArray);
		}
		
		public static function loadFriendFarm(id:String):void{
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var loaderVar:URLVariables = new URLVariables();
			
			//retrieve playerid from facebook
			loaderVar.facebookId = id;
			
			//php script to load the inventory	
			var loadFarmRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/get_player_farm.php"); //input check script url here
			loadFarmRequest.method = URLRequestMethod.POST;
			
			loadFarmRequest.data = loaderVar;
			
			//attempt loading of the inventory
			try{
				loader.load(loadFarmRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadFriendFarm(loader);});
			}catch(error:IOError){
				dump("unable to load friend's farm");	
			}			
		}
		
		//Completion function for loading player's farm
		public static function completeLoadFriendFarm(loader:URLLoader):void{
			
			//instantiate variables
			var decodedArray:Array = [];
			var incoming:String = loader.data;
			MainTimeLine.debugText.text = incoming;
			
			//checks if all incoming data are valid
			if((incoming.search("Warning")<0)&&(incoming.length>1)){
				//If valid, decoded array will be replaced by the
				//loaded data
				decodedArray = JSON.decode(incoming);				
			}else{
				dump("friend farm loading failed... please check database for errors");
			}
			
			//Assign to a friend farm
			//A current friend should have already been instantiated
			//Better assign it there in the following statement
		}
				
		public static function dump(myMessage:String):void{
			MainTimeLine.debugText.text = myMessage;
		}
		
		public static function savePlayerValues(player:Player):void{
			
			//set up variables to be stored
			var playerVars:URLVariables = new URLVariables();
			
			playerVars.diamond = player.diamond;
			playerVars.exp = player.exp;
			playerVars.expandLevel = 1;
			playerVars.gender = player.gender;
			playerVars.gold = player.gold;
			playerVars.level = player.level;
			playerVars.stamina = player.stamina;
			playerVars.facebookId = player.playerID;
			playerVars.lastLogIn = MainTimeLine.session.player.logInTime;
			playerVars.farmName = player.farmName;
			
			/*if (player.lastCount>0) {
				playerVars.lastCount = player.lastCount;
			} else {
				playerVars.lastCount = MainTimeLine.session.loginTime;
			}
			playerVars.count = player.count;*/
			
			//trace("SavePlayer here: "+playerVars.lastCount+" , "+playerVars.count);
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			//request
			var savePlayerRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/insert_update_player.php"); //input check script url here
			savePlayerRequest.method = URLRequestMethod.POST;
			
			savePlayerRequest.data = playerVars;
			//send the data and routs to handler function once completed
			try{
				loader.load(savePlayerRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{dump("player data sent")});
			}catch(error:IOError){
				dump("unable to save player");	
			}
		}
		
		public static function savePlayerInventory(player:Player):void{
			
			var itemData:String = JSON.encode(player.inventory.save());
			
			var inventoryVars:URLVariables = new URLVariables();
			inventoryVars.itemData = itemData;
			inventoryVars.facebookId = player.playerID;
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var saveInventoryRequest:URLRequest = new URLRequest(MainTimeLine.rootURL+"PHP/util/insert_update_player_inventory.php");
			saveInventoryRequest.method = URLRequestMethod.POST;
			
			saveInventoryRequest.data = inventoryVars;
			
			//send the data and routs to handler function once completed
			try{
				loader.load(saveInventoryRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{dump("inventory data sent")});
			}catch(error:IOError){
				dump("unable to save inventory");	
			}
		}
		
		public static function saveFarmRequest(player:Player):void{
			
		}
		
		// update volunteerID
		public static function updateVolunteerID(volunteerID:String){
			
			// update variables
			var loaderVar:URLVariables = new URLVariables();
			loaderVar.facebookId = MainTimeLine.session.player.playerID;
			loaderVar.volunteerID = volunteerID;
			
			// request
			var updateVolunteerIDRequest:URLRequest = new URLRequest(MainTimeLine.rootURL + "PHP/volunteer/updateVolunteerID.php");
			updateVolunteerIDRequest.data = loaderVar;
			
			var loader:URLLoader = new URLLoader();
			
			try{
				loader.load(updateVolunteerIDRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeUpdateVolunteerID(loader);});
			}
			catch(error:IOError){
				dump("login error");
			}
		}
		
		// complete update volunteer id
		private static function completeUpdateVolunteerID(loader:URLLoader){
			trace("complete update volunteer id");
		}
		
		// load plyaer volunteer reward
		public static function loadPlayerVolunteerReward():void{
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var loaderVar:URLVariables = new URLVariables();
			
			//retrieve playerid from facebook
			loaderVar.facebookId = MainTimeLine.session.player.playerID;
			
			//php script to load the attended count in month	
			var loadRequest:URLRequest = new URLRequest(MainTimeLine.rootURL + "PHP/volunteer/get_player_volunteer_reward.php"); //input check script url here
			loadRequest.method = URLRequestMethod.POST;
			
			loadRequest.data = loaderVar;
			
			try{
				loader.load(loadRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeLoadPlayerVolunteerReward(loader);});
			}catch(error:IOError){
				dump("unable to load player volunteer reward");	
			}			
		}
		
		// complete loading player volunteer reward, initialize in the game
		public static function completeLoadPlayerVolunteerReward(loader:URLLoader){
			var incoming:String = loader.data;
			
			if(incoming != "no result"){
				MainTimeLine.session.player.volunteer.volunteerReward.initVolunteerReward(JSON.decode(incoming)[0]);
			}
			else{
				MainTimeLine.session.player.volunteer.volunteerReward.initVolunteerReward(null);
				trace("no player volunteer reward");
			}
		}
		
		// update volunteer reward which player has left
		public static function updatePlayerVolunteerReward(outstandingReward:int){
			
			var loader:URLLoader = new URLLoader();
			loader.dataFormat = URLLoaderDataFormat.TEXT;
			
			var loaderVar:URLVariables = new URLVariables();
			
			//retrieve playerid from facebook
			loaderVar.facebookId = MainTimeLine.session.player.playerID;
			loaderVar.outstandingReward = outstandingReward;
			
			var loadRequest:URLRequest = new URLRequest(MainTimeLine.rootURL + "PHP/volunteer/update_player_volunteer_reward.php"); //input check script url here
			loadRequest.method = URLRequestMethod.POST;
			
			loadRequest.data = loaderVar;
			
			try{
				loader.load(loadRequest);
				loader.addEventListener(Event.COMPLETE, function(event:Event):void{completeUpdatePlayerVolunteerReward(loader);});
			}catch(error:IOError){
				dump("unable to update player volunteer reward");	
			}			
		}
		
		// complete update player volunteer reward
		public static function completeUpdatePlayerVolunteerReward(loader:URLLoader){
			trace("complete update player volunteer reward");
		}
	}
}